home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- /*----------------------------------------------------------------
- *
- * scrollmon - live video titling
- *
- *
- * 10.93 John Magdziarz, Silicon Graphics, Inc.
- * Last edit 04.07.94
- *
- *----------------------------------------------------------------*/
- char ident[] = "@(#)scrollmon Version 1.1, John Magdziarz 10.93";
-
- #include <scrollmon.h>
-
- extern void initVideo(Widget);
- extern Widget toplevel;
-
- extern void scrollCreds(XtPointer w, ulong *id);
- extern "C" {
- long *longimagedata(char *);
- int sizeofimage(char *, int *, int *);
- }
- extern createInterface(int *, char **);
-
- extern resources appResources;
- extern XtAppContext app_context;
- extern Widget glw;
-
- void grabTextBlocks(Widget, XtPointer , XtPointer);
- static void udpateStatBar(short);
-
- PerfCalc *timerPerf = new PerfCalc("timer");
- PerfCalc *frameRatePerf = new PerfCalc("frameRate");
- CredSection *credSects[100];
- int FRAMETIME = FALSE;
- int direction = 1;
- FColors fcolors;
- long bgcol;
- int swapCnt = 0;
- int dropped;
- int refreshRate = 60;
- int refreshIntvl;
- Boolean gfxSetupComplete = False;
- Boolean credMotion = True;
- Boolean videoBg = True;
- Boolean refresh = False;
- Boolean restart = False;
-
- ulong *tmpbuf;
-
- enum TokenType { FONTCMD, COLORCMD, IMAGECMD, LMARGINCMD, RMARGINCMD,
- BGCOLCMD, toklen };
- const int TOKENCNT = toklen + 1;
-
-
- typedef struct TokenStruct {
- char *name;
- enum TokenType token;
- };
-
- TokenStruct tokens[] = {
- {"FONT", FONTCMD},
- {"COLOR", COLORCMD},
- {"IMAGE", IMAGECMD},
- {"LMARGIN", LMARGINCMD},
- {"RMARGIN", RMARGINCMD}
- };
-
-
-
-
- static void
- setProcessPriority()
- {
- int result;
- pid_t pid;
-
- // switch priority to super-user
- setreuid(geteuid(), geteuid());
- setregid(getegid(), getegid());
-
- result = prctl(PR_RESIDENT);
- if (result == -1)
- fprintf(stderr, "unable to insure that process is memory-resident.\n");
-
- pid = getpid();
- result = schedctl(NDPRI, pid, NDPHIMIN);
- if (result == -1)
- fprintf(stderr, "unable to set process priority. need to run as root.\n");
-
- // resume our previous identity
- setreuid(getuid(), getuid());
- setregid(getgid(), getgid());
- }
-
-
- int
- determineJustification(CredSection *curSect, char c, ulong strWidth)
- {
- switch (c) {
- case 'C':
- return(appResources.winW / 2 - strWidth / 2);
- case 'R':
- return(appResources.winW - curSect->rMargin - strWidth);
- case 'L':
- return(curSect->lMargin);
- default:
- cout << "error in justification setting." << endl;
- }
- }
-
-
-
- void
- determineRefreshRate()
- {
- switch(getmonitor()) {
- case HZ50:
- refreshRate = 50;
- break;
- case HZ60:
- refreshRate = 60;
- break;
- case HZ72:
- refreshRate = 72;
- break;
- default:
- cout << "current refresh rate not supported" << endl;
- exit(0);
- }
- if (refreshRate != 50 && refreshRate != 60) {
- cout << endl;
- cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl;
- cout << "To get the update rate of the graphics to match the update rate" << endl;
- cout << "of your video standard you should set your monitor with setmon to" << endl;
- cout << "60HZ for NTSC or 50HZ for PAL. Additionally you can use the" << endl;
- cout << "-F option to setmon to set framelocking." << endl;
- }
- cout << endl;
- cout << "Currently your monitor refresh rate is " << refreshRate << "HZ" << endl;
- div_t rr = div(refreshRate, appResources.fps);
- if (rr.rem != 0) {
- cout << "You have selected " << appResources.fps << "fps" << endl;
- cout << "which is not possible. Rounding down to the next integral" << endl;
- cout << "multiple of the refresh rate: ";
- appResources.fps = refreshRate / (rr.quot + 1);
- cout << appResources.fps << "fps" << endl;
- cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl;
- }
- }
-
-
- void
- setRefreshFlag(Widget, XtPointer , XtPointer)
- {
- refresh = True;
- }
-
-
- void
- grabTextBlocks(Widget, XtPointer , XtPointer)
- {
- short x = 0;
- short y = 300;
- CredFont *credFont;
-
- if (!restart) {
- determineRefreshRate();
- }
-
- // XtRemoveCallback(glw, GlxNexposeCallback, grabTextBlocks, 0);
- readsource(SRC_BACK);
- cpack(bgcol);
- clear();
- swapbuffers();
- for ( int j = 0; j < CredSection::credSectCnt; j++ ) {
- if (credSects[j]->credType == FontTypeId) {
- credFont = (CredFont *)credSects[j];
- credFont->loadFontEnv();
- for ( int k = 0; k < credFont->credCnt; k++) {
- cpack(bgcol);
- clear();
- wfm_cpack(credFont->fontColor);
- wfm_cmov2i( x, y );
- credFont->image[k].width = (int)wfm_strwidth(credFont->getStr(k));
- credFont->image[k].height = credFont->size;
- credFont->image[k].xpos = determineJustification(credFont,
- credFont->fontJust[0],
- credFont->image[k].width);
- wfm_charstr( credFont->getStr(k) );
- credFont->image[k].imgBuf = new ulong[(credFont->image[k].width + 1) *
- (credFont->image[k].height + 1)];
- short x1 = x;
- short y1 = (short)(y - credFont->finfo.yorig);
- short x2 = (short)(x1 + credFont->image[k].width);
- if (x2 > appResources.winW)
- x2 = appResources.winW;
- short y2 = (short)(y1 + credFont->image[k].height);
- lrectread(x1, y1, x2, y2, credFont->image[k].imgBuf);
- }
- }
- }
- readsource(SRC_FRONT);
- refreshIntvl = (int)(refreshRate / appResources.fps);
- swapinterval(refreshIntvl);
- frameRatePerf->startTiming();
- gfxSetupComplete = True;
- refresh = True;
- }
-
-
-
- int
- getToken(char *directive)
- {
- for (int i = 0; i < TOKENCNT; i++)
- if (!strcmp(directive, tokens[i].name)) {
- return(tokens[i].token);
- }
- }
-
-
- void
- readImage(char *filename, int *xsize, int *ysize, ulong **buf)
- {
- *buf = (ulong *)longimagedata(filename);
- sizeofimage(filename, xsize, ysize);
- }
-
-
- void
- readCreditsFile()
- {
- const int lineSize = 255;
- char fFamily[80];
- char lineStr[lineSize];
- int fSize = 12;
- char fCname[80];
- long fColor;
- char fJust[80];
- float fAngle = 0;
- float fSpacing = 1;
- char directive[lineSize];
- static int lmargin = (int)(appResources.winW * 0.15);
- static int rmargin = (int)(appResources.winW * 0.15);
- CredFont *credFont;
- char imgFilename[80];
- int xsize, ysize;
- int xoff, yoff;
- ulong *buf;
-
- for (int i = 0; i < CredSection::credSectCnt; i++)
- delete credSects[i];
-
- CredSection::credSectCnt = 0;
- CredSection::totalCredHeight = 0;
-
- // Read in credits file
- // lines starting with ':' are directives for fonts, colors, images, etc.
- // lines starting with '#' are comment lines
- // all other lines are text lines
- ifstream credFile( appResources.credFilename, ios::in ) ;
- if ( !credFile ) {
- cerr << "unable to open file for input" << endl;
- exit(0);
- }
- char cname[80];
- int red;
- int green;
- int blue;
- while ( credFile.getline(lineStr, lineSize) ) {
- switch (lineStr[0]) {
- case ':':
- sscanf(lineStr, "%*c %s", directive);
- switch(getToken(directive)) {
- case FONTCMD:
- sscanf(lineStr, "%*c %s %s %d %s %s %f %f", directive,
- fFamily, &fSize, fCname,
- fJust, &fAngle, &fSpacing);
- fColor = fcolors.get(fCname) | 0xFF000000;
- credSects[CredSection::credSectCnt] = new CredFont(fFamily,
- fSize, fColor, fJust,
- fAngle, fSpacing);
- credSects[CredSection::credSectCnt]->credType = FontTypeId;
- credSects[CredSection::credSectCnt]->setLMargin(lmargin);
- credSects[CredSection::credSectCnt]->setRMargin(rmargin);
- CredSection::credSectCnt++;
- if (appResources.debug)
- cout << "fontFamily = " << fFamily << " size = " << fSize << endl;
- break;
- case IMAGECMD:
- sscanf(lineStr, "%*c %s %s %d %d", directive, imgFilename, &xoff,
- &yoff);
- readImage(imgFilename, &xsize, &ysize, &buf);
- tmpbuf = buf;
- credSects[CredSection::credSectCnt] = new CredImage(xoff, yoff,
- xsize - 1,
- ysize - 1, buf);
- credSects[CredSection::credSectCnt]->credType = ImageTypeId;
- credSects[CredSection::credSectCnt]->credCnt++;
- CredSection::credSectCnt++;
- break;
- case COLORCMD:
- sscanf(lineStr, "%*c %s %d %d %d %s", directive,
- &red, &green, &blue, cname);
- if (appResources.debug)
- cout << "color " << cname << " defined" << endl;
- fcolors.add(red, green, blue, cname);
- break;
- case LMARGINCMD:
- sscanf(lineStr, "%*c %s %d", directive, &lmargin);
- if (appResources.debug)
- cout << "LMARGIN set to " << lmargin << endl;
- break;
- case RMARGINCMD:
- sscanf(lineStr, "%*c %s %d", directive, &rmargin);
- break;
- case BGCOLCMD:
- sscanf(lineStr, "%*c %s %d", directive, &bgcol);
- break;
- }
- break;
- case '#': break;
- default:
- credFont = (CredFont *)credSects[CredSection::credSectCnt - 1];
- credFont->addStr(lineStr);
- break;
- }
- }
- credFile.close();
- cout << "projected time to scroll: " << (CredSection::totalCredHeight +
- appResources.winH) / (appResources.fps * appResources.speed) << " secs"
- << endl;
- }
-
-
- static void
- updateStatBar(float perf)
- {
- static short zoneLen = 120;
-
- cpack(0x00FF00);
- rectfs(0, appResources.winH, zoneLen, appResources.winH - 40);
- cpack(0x00FFFF);
- rectfs(zoneLen + 1, appResources.winH, zoneLen * 2, appResources.winH - 40);
- if (dropped)
- cpack(0x0000FF);
- else
- cpack(0xFF0000);
- rectfs(0, appResources.winH - 10, (short)(ceilf((appResources.fps/(1/perf))
- * zoneLen)), appResources.winH - 30);
- }
-
-
- void
- initText()
- {
- wfm_init();
- wfm_hint(FONTHINT_ROUNDADVANCE, 0);
- wfm_hint(FONTHINT_SCALETHRESH, 40);
- wfm_hint(FONTHINT_MINOUTLINESIZE, 20);
- wfm_hint(FONTHINT_AABITMAPFONTS, 0);
- wfm_hint(FONTHINT_SCALETHRESH, 10);
- wfm_hint(FONTHINT_MAXAASIZE, 200);
- wfm_aacpack(0xFF000000, 0xB0000000);
- }
-
-
- void
- scrollCreds(XtPointer, ulong *)
- {
- short xpos = 0;
- short ypos = 0;
- int leading;
- int credYoff = 0;
- static int credPosY = 0;
- static int credUpdateY = 0;
- static float gfxIntvl = 0;
- static int nframes = 0;
-
- if (appResources.debug)
- timerPerf->startTiming();
-
- if (restart) {
- credPosY = 0;
- credUpdateY =0;
- restart = False;
- }
-
- credUpdateY = appResources.speed * direction;
- cpack(fcolors.get("black"));
- clear();
- for ( int j = 0; j < CredSection::credSectCnt; j++ ) {
- leading = (int)(credSects[j]->size * credSects[j]->spacing);
- for ( int k = 0; k < credSects[j]->credCnt; k++) {
- xpos = credSects[j]->image[k].xpos + credSects[j]->xoff;
- ypos = credPosY - credYoff - ((k + 1) * leading) + credSects[j]->yoff;
- if (ypos > -credSects[j]->size && ypos < appResources.winH)
- if ((ypos - appResources.speed) > 0 && ypos < appResources.winH
- && !refresh)
- rectcopy(xpos, credSects[j]->image[k].lastY,
- xpos + credSects[j]->image[k].width,
- credSects[j]->image[k].lastY +
- credSects[j]->image[k].height,
- xpos, ypos);
- else
- lrectwrite(xpos, ypos, xpos + credSects[j]->image[k].width,
- ypos + credSects[j]->image[k].height,
- credSects[j]->image[k].imgBuf);
- credSects[j]->image[k].lastY = ypos;
- }
- credYoff += credSects[j]->credCnt * leading;
- }
- refresh = False;
- credPosY += credUpdateY;
- if (ypos > appResources.winH) {
- credPosY = 0;
- float fr = frameRatePerf->getInterval();
- if (appResources.perf)
- cout << swapCnt << " frames during " << fr << " secs, " <<
- floorf(appResources.fps * fr) - swapCnt << " frames dropped" << endl;
- frameRatePerf->startTiming();
- swapCnt = 0;
- }
- if (appResources.perf)
- updateStatBar(gfxIntvl);
- finish();
- if (appResources.perf)
- gfxIntvl = timerPerf->getInterval();
- }
-
-
- void
- swapGfx()
- {
- swapbuffers();
- swapCnt++;
- }
-
-
- void
- updateGfx()
- {
- XEvent event;
- static int refreshes = 0;
- XtInputMask mask;
- if (credMotion) {
- scrollCreds((XtPointer)0, (ulong *)0);
- swapGfx();
- if (mask = XtAppPending(app_context)) {
- XtAppProcessEvent(app_context, mask);
- }
- }
- else {
- XtAppNextEvent(app_context, &event);
- XtDispatchEvent(&event);
- }
- }
-
-
- main(int argc, char **argv)
- {
- XEvent event;
-
- createInterface(&argc, argv);
- setProcessPriority();
-
- // initVideo(toplevel);
-
- readCreditsFile();
- initText();
-
- XtAddCallback(glw, GlxNexposeCallback, grabTextBlocks, 0);
-
- while (!gfxSetupComplete) {
- XtAppNextEvent(app_context, &event);
- XtDispatchEvent(&event);
- }
-
- while(1)
- updateGfx();
- }
-